#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect(ui->btn_Send,&QPushButton::clicked,this,&MainWindow::sendInfo);
    connect(ui->btn_openPort,&QPushButton::clicked,this,&MainWindow::openPort);   
    initUi();
}

MainWindow::~MainWindow()
{
    delete ui;
}

QStringList MainWindow::getPortNameList()
{
    QStringList m_serialPortName;
    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
        m_serialPortName<<info.portName();
        ui->comboBox_PortName->addItem(info.portName());
        qDebug()<<"portName："<<info.portName();
    }
    return m_serialPortName;
}

void MainWindow::openPort()
{
    //如果串口已经打开了 先给他关闭了
    if(m_serialPort->isOpen()){
        m_serialPort->clear();
        m_serialPort->close();
    }
    //当前选择的串口名字
    m_serialPort->setPortName(ui->comboBox_PortName->currentText());
    //用ReadWrite 的模式尝试打开串口
    if(!m_serialPort->open(QIODevice::ReadWrite)){
        qDebug()<<"打开失败!";
        return;
    }
    qDebug()<<"串口打开成功!";
    m_serialPort->setBaudRate(QSerialPort::Baud9600,QSerialPort::AllDirections);//设置波特率和读写方向
    m_serialPort->setDataBits(QSerialPort::Data8);      //数据位为8位
    m_serialPort->setFlowControl(QSerialPort::NoFlowControl);//无流控制
    m_serialPort->setParity(QSerialPort::NoParity); //无校验位
    m_serialPort->setStopBits(QSerialPort::OneStop); //一位停止位

    connect(m_serialPort,&QSerialPort::readyRead,this,&MainWindow::receiveInfo);

}

void MainWindow::receiveInfo()
{
    QByteArray info = m_serialPort->readAll();

    qDebug()<<"receive info:"<<info;

    QByteArray hexData = info.toHex();
     qDebug()<<"hexData:"<<hexData;
    //这里面的协议 你们自己定义就行  单片机发什么 代表什么 我们这里简单模拟一下
    if(hexData == "0x00")
    {
        //do something

    }
    else if(hexData  == "0x00")
    {
        //do something

    }
}

void MainWindow::initUi()
{
    this->setWindowTitle("串口通信测试");
    m_serialPort = new QSerialPort;
    m_portNameList=getPortNameList();

}

void MainWindow::sendInfo()
{
    QString text=ui->plainTextEdit_Send->toPlainText();
    //text+="\n";
    QByteArray ba;
    convertStringToHex(text,ba);
    //ba=ba.toHex();
    qDebug()<<"发送："<<ba;
    qint64 x= m_serialPort->write(ba);//这句是真正的给单片机发数据 用到的是QIODevice::write

    qDebug()<<x;
}


//基本和单片机交互 数据 都是16进制的 我们这里自己写一个 Qstring 转为 16进制的函数
void MainWindow::convertStringToHex(const QString &str, QByteArray &byteData)
    {
        int hexdata,lowhexdata;
        int hexdatalen = 0;
        int len = str.length();
        byteData.resize(len/2);
        char lstr,hstr;
        for(int i=0; i<len; )
        {
            //char lstr,
            hstr=str[i].toLatin1();
            if(hstr == ' ')
            {
                i++;
                continue;
            }
            i++;
            if(i >= len)
                break;
            lstr = str[i].toLatin1();
            hexdata = convertCharToHex(hstr);
            lowhexdata = convertCharToHex(lstr);
            if((hexdata == 16) || (lowhexdata == 16))
                break;
            else
                hexdata = hexdata*16+lowhexdata;
            i++;

            byteData[hexdatalen] = (char)hexdata;
            hexdatalen++;
        }
        byteData.resize(hexdatalen);
        //qDebug()<<"byda:"<<byteData;
}

void MainWindow::test(QString s, QString &str)
{
    str=s;
    qDebug()<<"str=="<<str;
}

//另一个 函数 char 转为 16进制
char MainWindow::convertCharToHex(char ch)
    {
        /*
        0x30等于十进制的48，48也是0的ASCII值，，
        1-9的ASCII值是49-57，，所以某一个值－0x30，，
        就是将字符0-9转换为0-9

        */
        if((ch >= '0') && (ch <= '9'))
             return ch-0x30;
         else if((ch >= 'A') && (ch <= 'F'))
             return ch-'A'+10;
         else if((ch >= 'a') && (ch <= 'f'))
             return ch-'a'+10;
         else return (-1);
}


